package org.dicr.util.jds.gui;

import java.awt.event.*;
import java.sql.Date;
import java.util.*;

import org.dicr.event.*;
import org.dicr.gui.*;

import com.borland.dx.dataset.*;

/***********************************************************************************************************************
 * @author Igor A Tarasov me@dicr.dn.ua
 * @version 021210
 **********************************************************************************************************************/
public class DataDateField extends DateField implements ColumnAware {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected DataSet dataset = null;

	protected String columnName = null;

	protected boolean ignoreDataChanges = false;

	protected DataListener dataListener = new DataListener();

	/*******************************************************************************************************************
	 * Обновление календаря при изменении данных
	 ******************************************************************************************************************/
	protected void updateModel() {
		Date date = isValidDataSetState() ? this.dataset.getDate(this.columnName) : null;
		if (date != null) try {
			this.calendar.setTime(date);
		} catch (Exception e) {
			// NOP
		} finally {
			fixCalendar();
		}
		else this.calendar.set(Calendar.DAY_OF_MONTH, -1);
		updateComponents();
		fireActionEvent("dataChange");
	}

	/*******************************************************************************************************************
	 * Вызывается при изменении данных в компоненте
	 ******************************************************************************************************************/
	protected void updateData() {
		if (isValidDataSetState()) try {
			Date date = null;
			if (isDateComplete()) date = new Date(this.calendar.getTime().getTime());
			this.dataset.setDate(this.columnName, date);
			fireActionEvent("valueChange");
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
	 * Устанавливает источник данных
	 ******************************************************************************************************************/
	@Override
    public void setDataSet(DataSet theDataSet) {
		if (this.dataset != theDataSet) {
			if (this.dataset != null) {
				this.dataset.removeAccessListener(this.dataListener);
				this.dataset.removeNavigationListener(this.dataListener);
				this.dataset.removeDataChangeListener(this.dataListener);
			}
			this.dataset = theDataSet;
			try {
				if (theDataSet != null) {
					theDataSet.addAccessListener(this.dataListener);
					theDataSet.addNavigationListener(this.dataListener);
					theDataSet.addDataChangeListener(this.dataListener);
					theDataSet.open();
				}
			} finally {
				updateModel();
			}
		}
	}

	/*******************************************************************************************************************
	 * Возвращает источник данных
	 ******************************************************************************************************************/
	@Override
    public DataSet getDataSet() {
		return this.dataset;
	}

	/*******************************************************************************************************************
	 * Устанавливает имя колонки источника данных
	 ******************************************************************************************************************/
	@Override
    public void setColumnName(String name) {
		if (this.columnName != name) {
			this.columnName = name;
			updateModel();
		}
	}

	/*******************************************************************************************************************
	 * Возвращает имя колонки источника данных
	 ******************************************************************************************************************/
	@Override
    public String getColumnName() {
		return this.columnName;
	}

	/*******************************************************************************************************************
	 * Проверяет корректность установки источника данных
	 ******************************************************************************************************************/
	protected boolean isValidDataSetState() {
		return (this.columnName != null && this.dataset != null && this.dataset.isOpen());
	}

	/*******************************************************************************************************************
	 * ######################################################################### Слушатель изменения данных
	 * #########################################################################
	 ******************************************************************************************************************/
	class DataListener extends DataChangeAdapter implements AccessListener, NavigationListener {
		/***************************************************************************************************************
		 * Обработчик события изменения доступа к источнику данных
		 **************************************************************************************************************/
		@Override
        public void accessChange(AccessEvent event) {
			DataDateField.this.ignoreDataChanges = (event.getID() == AccessEvent.CLOSE);
			updateModel();
		}

		/***************************************************************************************************************
		 * Обработчик события перемещения по данным
		 **************************************************************************************************************/
		@Override
        public void navigated(NavigationEvent event) {
			if (!DataDateField.this.ignoreDataChanges) updateModel();
		}

		/***************************************************************************************************************
		 * Обработчик изменения данных
		 **************************************************************************************************************/
		@Override
		public void postRow(DataChangeEvent e) {
			if (!DataDateField.this.ignoreDataChanges) updateModel();
		}
	}

	/*******************************************************************************************************************
	 * Обработчик событий компонента
	 ******************************************************************************************************************/
	@Override
	public void actionPerformed(ActionEvent e) {
		super.actionPerformed(e);
		if (isDateComplete()) updateData();
	}
}
